package com.ccom.starter.file.serviceImpl;

import com.ccom.core.common.exception.CcomBootException;
import com.ccom.starter.file.service.OOSService;
import io.minio.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.Map;

/**
 * minio默认实现
 */
public class OOSServiceMinioImpl implements OOSService {

    private static Logger logger = LoggerFactory.getLogger(OOSServiceMinioImpl.class);
    /**
     * 默认桶
     */
    private String bucketName;
    /**
     * MinioClient客户端
     */
    private MinioClient minioClient;
    /**
     * 用于对接数据中心amazon s3的copyObject、putObject接口，key、value由数据中心提供，可缺省
     */
    private Map<String, String> dateKeyValueMap;

    public OOSServiceMinioImpl(String bucketName, MinioClient minioClient, Map<String, String> dateKeyValueMap) {
        this.bucketName = bucketName;
        this.minioClient = minioClient;
        this.dateKeyValueMap = dateKeyValueMap;
    }

    private String bucketName() {
        return this.bucketName;
    }

    @Override
    public void uploadFile(String oosKey, InputStream in) {
        try {
            boolean exists = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName()).build());
            if (!exists) {
                minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName()).build());
            }
            if (null != dateKeyValueMap) {
                minioClient.putObject(PutObjectArgs.builder()
                        .bucket(bucketName())
                        .object(oosKey)
                        .stream(in, -1, ObjectWriteArgs.MIN_MULTIPART_SIZE)
                        .userMetadata(dateKeyValueMap)
                        .build());
            } else {
                minioClient.putObject(PutObjectArgs.builder()
                        .bucket(bucketName())
                        .object(oosKey)
                        .stream(in, -1, ObjectWriteArgs.MIN_MULTIPART_SIZE)
                        .build());
            }
        } catch (Exception e) {
            logger.error("上传文件到minio出错,bucket:{},oosKey:{}", bucketName(), oosKey);
            throw new CcomBootException(e.getMessage());
        }
    }

    @Override
    public InputStream downloadFile(String oosKey) {
        try {
            return minioClient.getObject(GetObjectArgs.builder()
                    .bucket(bucketName())
                    .object(oosKey)
                    .build());
        } catch (Exception e) {
            logger.warn("从minio下载文件出错或文件不存在,bucket:{},oosKey:{}", bucketName(), oosKey);
        }
        return null;
    }

    @Override
    public void deleteFile(String oosKey) {
        try {
            minioClient.removeObject(RemoveObjectArgs.builder()
                    .bucket(bucketName())
                    .object(oosKey)
                    .build());
        } catch (Exception e) {
            logger.warn("从minio删除文件出错或文件不存在,bucket:{},oosKey:{}", bucketName(), oosKey);
        }
    }

    @Override
    public boolean existsFile(String oosKey) {
        try {
            minioClient.statObject(StatObjectArgs.builder()
                    .bucket(bucketName())
                    .object(oosKey)
                    .build());
            return true;
        } catch (Exception e) {
            logger.warn("判断minio是否存在文件出错,oosKey:{}", oosKey);
            e.printStackTrace();
        }
        return false;
    }

    @Override
    public void copy(String from, String target) {
        try {
            CopySource source = CopySource.builder()
                    .bucket(bucketName())
                    .object(from)
                    .build();
            minioClient.copyObject(CopyObjectArgs.builder()
                    .bucket(bucketName())
                    .source(source)
                    .object(target)
                    .build());
        } catch (Exception e) {
            logger.error("从minio拷贝文件出错或文件不存在,bucket:" + bucketName() + ",from:" + from + ",target:" + target, e);
            throw new CcomBootException(e.getMessage());
        }
    }

    @Override
    public void uploadFile(String oosKey, String content) {
        try (InputStream inputStream = new ByteArrayInputStream(content.getBytes(StandardCharsets.UTF_8))) {
            uploadFile(oosKey, inputStream);
        } catch (IOException e) {
            logger.error("上传文件到minio出错", e);
        }
    }

    @Override
    public void uploadflowBatchResult(File file) {
        String oosKey = "flowBatchResult/" + file.getName();
        try (InputStream is = new FileInputStream(file)) {
            uploadFile(oosKey, is);
        } catch (Exception e) {
            logger.error("uploadflowBatchResult", e);
            throw new CcomBootException(e.getMessage());
        }
    }

    @Override
    public InputStream downloadFileByBucket(String oosKey, String bucketName) {
        try {
            return minioClient.getObject(GetObjectArgs.builder()
                    .bucket(bucketName)
                    .object(oosKey)
                    .build());
        } catch (Exception e) {
            logger.warn("从minio下载文件出错或文件不存在,bucket:{},oosKey:{}", bucketName, oosKey);
        }
        return null;
    }

    @Override
    public void uploadFileByBucket(String bucketName, String oosKey, InputStream in) {
        try {
            if (null != dateKeyValueMap) {
                minioClient.putObject(PutObjectArgs.builder()
                        .bucket(bucketName)
                        .object(oosKey)
                        .stream(in, -1, ObjectWriteArgs.MIN_MULTIPART_SIZE)
                        .userMetadata(dateKeyValueMap)
                        .build());
            } else {
                minioClient.putObject(PutObjectArgs.builder()
                        .bucket(bucketName)
                        .object(oosKey)
                        .stream(in, -1, ObjectWriteArgs.MIN_MULTIPART_SIZE)
                        .build());
            }
        } catch (Exception e) {
            logger.error("上传文件到minio出错,bucket:{},oosKey:{}", bucketName, oosKey);
            throw new CcomBootException(e.getMessage());
        }
    }
}
